﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows.Data;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;
using FileTransfer.Client;
using FileTransferDesktop.Extensions;
using FileTransferDesktop.Message;
using FileTransferDesktop.Models;
using FileTransferDesktop.Services;
using FileTransferDesktop.ViewModels.Controls;
using FileTransferDesktop.ViewModels.Dialogs;
using FileTransferDesktop.Views.Dialogs;
using Microsoft.Extensions.Logging;
using MessageEditDialogViewModel = FileTransferDesktop.ViewModels.Dialogs.MessageEditDialogViewModel;

namespace FileTransferDesktop.ViewModels.Pages;

public partial class UploadTask : ObservableObject
{
    // API客户端，由UploadViewModel设置
    public ApiClient? ApiClient { get; set; }

    [ObservableProperty]
    private bool _isSelected = false;

    [ObservableProperty]
    private string _name = string.Empty;

    [ObservableProperty]
    private string _status = string.Empty;

    [ObservableProperty]
    private string _path = string.Empty;

    [ObservableProperty]
    private string _progress = string.Empty;

    [ObservableProperty]
    private string _shareCode = string.Empty;

    [ObservableProperty]
    private string _message = string.Empty;

    [ObservableProperty]
    private DateTime _createdTime = DateTime.Now;

    [ObservableProperty]
    private string _editToken = string.Empty; // 编辑token，用于后端API调用

    // 新增：编辑状态相关属性
    [ObservableProperty]
    private bool _isEditingMessage = false;

    [ObservableProperty]
    private string _editingMessage = string.Empty;

    // 开始编辑消息命令
    [RelayCommand]
    private void StartEditMessage()
    {
        EditingMessage = Message;
        IsEditingMessage = true;
    } // 保存消息命令

    [RelayCommand]
    private async Task SaveMessage()
    {
        Message = EditingMessage;
        IsEditingMessage = false;

        // 更新数据库
        var id = await LocalDbService.GetUploadIdByTimeAsync(CreatedTime);
        if (id != null)
        {
            await LocalDbService.UpdateUploadMessageAsync(id, Message);
        }

        // 调用后端API更新消息
        if (
            !string.IsNullOrEmpty(ShareCode)
            && !string.IsNullOrEmpty(EditToken)
            && ApiClient != null
        )
        {
            try
            {
                await ApiClient.MessageControllerApi.AddMessageAsync(ShareCode, EditToken, Message);
            }
            catch (Exception ex)
            {
                // 记录错误，但不阻止用户操作
                System.Diagnostics.Debug.WriteLine(
                    $"Failed to update message via API: {ex.Message}"
                );
            }
        }
    } // 取消编辑命令

    [RelayCommand]
    private void CancelEditMessage()
    {
        EditingMessage = string.Empty;
        IsEditingMessage = false;
    } // 打开消息编辑对话框命令

    [RelayCommand]
    private async Task OpenMessageEditDialog()
    {
        if (string.IsNullOrEmpty(ShareCode) || string.IsNullOrEmpty(EditToken) || ApiClient == null)
            return;

        try
        {
            var dialogVm = new MessageEditDialogViewModel(ApiClient);
            var dialog = new FileTransferDesktop.Views.Dialogs.MessageEditDialog(dialogVm);

            await dialogVm.LoadMessagesAsync(ShareCode, EditToken);
            await dialog.ShowAsync();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"Failed to open message edit dialog: {ex.Message}");
        }
    }
}

public partial class UploadViewModel : ObservableObject
{
    private readonly ApiClient _api;
    private readonly IServiceProvider _serviceProvider;
    public CollectionView<UploadTask> UploadTasksView { get; init; }
    private bool _isUpdatingByCode = false;
    private DateTime _lastUpdate = DateTime.MinValue;

    public SpeedChartViewModel SpeedChartVm { get; } = new();

    [ObservableProperty]
    private ObservableCollection<UploadTask> _uploadTasks = [];

    [ObservableProperty]
    private int _selectedTabIndex;

    [ObservableProperty]
    private string _filterText = string.Empty;

    [ObservableProperty]
    private bool? _allSelected = false;

    public UploadViewModel(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
        _api = serviceProvider.CreateApiClient();
        UploadTasks.CollectionChanged += (_, e) =>
        {
            if (e.NewItems != null)
            {
                foreach (UploadTask task in e.NewItems)
                {
                    task.PropertyChanged += UploadTaskPropertyChanged;
                }
            }

            if (e.OldItems != null)
            {
                foreach (UploadTask task in e.OldItems)
                {
                    task.PropertyChanged -= UploadTaskPropertyChanged;
                }
            }

            Application.Current.Dispatcher.BeginInvoke(UpdateAllSelectedState);
            return;

            void UploadTaskPropertyChanged(object? sender, PropertyChangedEventArgs e)
            {
                if (e.PropertyName == nameof(UploadTask.IsSelected))
                {
                    UpdateAllSelectedState();
                }
            }
        };

        UploadTasksView = CollectionViewSource.GetDefaultView(UploadTasks).Cast<UploadTask>();
        UploadTasksView.Filter = FilterUploadTasks;
        UploadTasksView.SortDescriptions.Add(
            new SortDescription(nameof(UploadTask.CreatedTime), ListSortDirection.Descending)
        );
        InitUploadTasks();
    }

    private void InitUploadTasks()
    {
        var records = LocalDbService.GetAllUploads();
        var uploadTasks = records
            .Select(r => new UploadTask
            {
                Name = r.FileName,
                Status = r.Status,
                ShareCode = r.ShareCode,
                CreatedTime = r.UploadTime,
                Progress = "---",
                Message = r.Message,
                EditToken = r.EditToken, // 设置EditToken
                IsSelected = false,
                ApiClient = _api, // 设置API客户端
            })
            .ToList();

        UploadTasks.Clear();
        foreach (var task in uploadTasks)
        {
            UploadTasks.Add(task);
        }
        Application.Current.Dispatcher.InvokeAsync(
            () =>
            {
                UploadTasksView.Refresh();
                UpdateAllSelectedState();
            },
            DispatcherPriority.Loaded
        );
    }

    partial void OnAllSelectedChanged(bool? oldValue, bool? newValue)
    {
        if (_isUpdatingByCode)
            return;
        var viewList = UploadTasksView.ToArray();
        if (!oldValue.HasValue)
        {
            AllSelected = true;
            return;
        }
        switch (newValue)
        {
            case false:
            {
                foreach (var task in viewList)
                    task.IsSelected = false;
                break;
            }
            case true:
            {
                foreach (var task in viewList)
                    task.IsSelected = true;
                break;
            }
        }
    }

    partial void OnSelectedTabIndexChanged(int value)
    {
        // 延迟刷新以避免同步问题
        Application.Current.Dispatcher.BeginInvoke(() =>
        {
            UploadTasksView.Refresh();
            UpdateAllSelectedState();
        });
    }

    private void UpdateAllSelectedState()
    {
        _isUpdatingByCode = true;

        try
        {
            var viewList = UploadTasksView.ToArray();

            if (viewList.Length == 0)
            {
                AllSelected = false;
                return;
            }

            var selectedCount = viewList.Count(t => t.IsSelected);

            if (selectedCount == viewList.Length)
            {
                AllSelected = true;
            }
            else if (selectedCount == 0)
            {
                AllSelected = false;
            }
            else
            {
                AllSelected = null;
            }
        }
        finally
        {
            _isUpdatingByCode = false;
        }
    }

    private bool FilterUploadTasks(object obj)
    {
        if (obj is not UploadTask task)
            return false;

        // Tab筛选
        switch (SelectedTabIndex)
        {
            case 1: // 已上传
                if (task.Status != "已上传")
                    return false;
                break;
            case 2: // 未完成
                if (task.Status != "上传中" && task.Status != "等待中" && task.Status != "失败")
                    return false;
                break;
            // case 0: // 全部上传，不筛选
        }

        return true;
    }

    [RelayCommand]
    private void ClearAll()
    {
        var toRemove = UploadTasksView.Where(t => t.IsSelected).ToArray();

        // 先从数据库删除
        foreach (var task in toRemove)
        {
            var id = LocalDbService.GetUploadIdByTime(task.CreatedTime);
            if (id != null)
            {
                LocalDbService.DeleteUpload(id);
            }
        }

        WeakReferenceMessenger.Default.Send(new RecycleBinChangedMessage());

        // 从ObservableCollection中移除
        foreach (var task in toRemove)
        {
            UploadTasks.Remove(task);
        }

        // 强制刷新CollectionView
        UploadTasksView.Refresh();
        UpdateAllSelectedState();
    }

    [RelayCommand]
    private async Task OpenUploadDialogAsync()
    {
        try
        {
            var dialogVm = new UploadDialogViewModel();
            var dialog = new UploadDialog(dialogVm);

            dialogVm.OnConfirm = void () =>
            {
                try
                {
                    dialog.Hide();
                    _ = Task.Run(async () =>
                    {
                        await StartUploadAsync(dialogVm.FileItems, dialogVm.GlobalAdditionalInfo);
                    });
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"Upload error: {ex.Message}");
                }
            };

            dialogVm.RequestClose = () => dialog.Hide();

            await dialog.ShowAsync();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"Dialog error: {ex.Message}");
        }
    }

    private async Task StartUploadAsync(
        ObservableCollection<UploadFileItem> fileItem,
        string additionalInfo = ""
    )
    {
        var tasks = await Task.Run(() =>
        {
            var validFiles = fileItem.Where(item => File.Exists(item.FilePath)).ToList();

            if (validFiles.Count == 0)
            {
                return [];
            }

            return validFiles
                .Select(item => new UploadTask
                {
                    IsSelected = false,
                    Name = item.FileName,
                    Path = item.FilePath,
                    Status = "等待中",
                    Progress = "0%",
                    ShareCode = "---",
                    CreatedTime = DateTime.Now,
                    Message = string.IsNullOrWhiteSpace(additionalInfo) ? "" : additionalInfo,
                })
                .ToList();
        });

        if (tasks.Count == 0)
        {
            return;
        }

        const int mbSizeUnit = 1024 * 1024;
        const int chunkSize = 20 * mbSizeUnit;

        var loggerFactory = LoggerFactory.Create(builder =>
            builder.AddConsole().SetMinimumLevel(LogLevel.Information)
        );
        await Application.Current.Dispatcher.InvokeAsync(() =>
        {
            foreach (var task in tasks)
            {
                task.ApiClient = _api; // 设置API客户端
                UploadTasks.Add(task);
            }
        });

        try
        {
            var shareCollection = new ShareCollection(_api, chunkSize, loggerFactory);
            foreach (var task in tasks)
            {
                await Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    task.Status = "上传中";
                    task.Progress = "0%";
                    SpeedChartVm.SetTransferLabel("正在传输数据");
                });

                var file = new FileInfo(task.Path);
                var lastProgressInfo = (
                    ProgressPercentage: 0.0,
                    TotalBytesWritten: 0L,
                    TotalContentLength: 0L
                );

                await shareCollection.AddFileAsync(
                    file,
                    progress =>
                    {
                        var now = DateTime.Now;

                        // 保存最后的进度信息，无论是否更新UI
                        if (progress.TotalContentLength == progress.TotalBytesWritten)
                            lastProgressInfo = (
                                progress.ProgressPercentage,
                                progress.TotalBytesWritten,
                                progress.TotalContentLength
                            );

                        if ((now - _lastUpdate).TotalMilliseconds < 100)
                            return;
                        _lastUpdate = now;

                        // 使用BeginInvoke而不是Invoke避免阻塞
                        Application.Current.Dispatcher.BeginInvoke(() =>
                        {
                            task.Progress = $"{progress.ProgressPercentage:F1}%";
                            SpeedChartVm.SetProgressPercentage(progress.ProgressPercentage);
                            SpeedChartVm.UpdateProgress(progress.TotalBytesWritten);
                            SpeedChartVm.UpdateTransferProgress(
                                progress.TotalBytesWritten,
                                progress.TotalContentLength
                            );
                        });
                    }
                );

                // 文件上传完成后，强制更新到最终状态
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    // 确保显示100%进度
                    task.Progress = "100%";
                    SpeedChartVm.SetProgressPercentage(100.0);

                    // 如果有最后的进度信息，使用它来更新图表
                    if (lastProgressInfo.TotalContentLength > 0)
                    {
                        SpeedChartVm.UpdateProgress(lastProgressInfo.TotalBytesWritten);
                        SpeedChartVm.UpdateTransferProgress(
                            lastProgressInfo.TotalBytesWritten,
                            lastProgressInfo.TotalContentLength
                        );
                    }
                });
            }

            var result = await shareCollection.MakeShareAsync();
            if (string.IsNullOrWhiteSpace(additionalInfo))
            {
                await _api.MessageControllerApi.AddMessageAsync(
                    result.Share.Code,
                    result.EditToken,
                    additionalInfo
                );
            }
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                SpeedChartVm.StartDecay(200);
                SpeedChartVm.SetTransferLabel("数据传输完成");

                foreach (var task in tasks)
                {
                    task.Status = "已上传";
                    task.Message = string.IsNullOrWhiteSpace(additionalInfo) ? "" : additionalInfo;
                    task.ShareCode = result.Share.Code;
                    task.EditToken = result.EditToken; // 设置EditToken
                    // 确保最终进度显示为100%
                    task.Progress = "100%";

                    Task.Run(() =>
                        LocalDbService.SaveUpload(
                            new UploadRecord
                            {
                                FileName = task.Name,
                                FilePath = task.Path,
                                UploadTime = task.CreatedTime,
                                ShareCode = result.Share.Code,
                                Status = "已上传",
                                Message = task.Message,
                                EditToken = result.EditToken, // 保存EditToken到数据库
                            }
                        )
                    );
                }
            });
        }
        catch (Exception ex)
        {
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                SpeedChartVm.SetTransferLabel("数据传输失败");

                foreach (var task in tasks)
                {
                    task.Status = "失败";
                    task.Message = string.IsNullOrWhiteSpace(additionalInfo)
                        ? ex.Message
                        : $"{additionalInfo}  失败：{ex.Message} ";
                    task.EditToken = ""; // 失败时EditToken为空

                    // 异步保存到数据库，不阻塞UI
                    Task.Run(() =>
                        LocalDbService.SaveUpload(
                            new UploadRecord
                            {
                                FileName = task.Name,
                                FilePath = task.Path,
                                UploadTime = task.CreatedTime,
                                ShareCode = "---",
                                Status = "失败",
                                Message = task.Message,
                                EditToken = "", // 失败时EditToken为空
                            }
                        )
                    );
                }
            });
        }
        finally
        {
            await Application.Current.Dispatcher.BeginInvoke(UpdateAllSelectedState);
            WeakReferenceMessenger.Default.Send(new MyShareChangedMessage());
        }
    }
}
